import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhangdi
 * @version 1.0
 * @date 2024.7.27
 */
public class AAA {
    private final long epoch; // 自定义纪元时间，比如系统启动时间
    private final AtomicInteger sequence = new AtomicInteger(0); // 使用AtomicInteger来处理并发

    public AAA(long epoch) {
        this.epoch = epoch;
    }

    public synchronized String generateId() {
        long currentTimeMillis = System.currentTimeMillis();
        // 假设我们只关心时间戳的某个低8位部分（这里为了示例，我们直接取低8位）
        // 注意：这通常不是一个好的做法，因为它会导致ID快速重复
        long timePart = (currentTimeMillis - epoch) % 256; // 256 = 2^8

        // 序列号的低4位
        int sequencePart = sequence.getAndIncrement() & 0xF; // 0xF = 0000 1111

        // 拼接ID（这里我们实际上没有生成一个真正的12位数字，因为timePart只有8位）
        // 但为了符合您的要求，我们假设timePart和sequencePart能够“合并”成一个看似12位的数字
        // 在实际应用中，您可能需要调整ID的结构或使用其他方法来确保唯一性
        long combined = (timePart << 4) | sequencePart; // 左移4位为sequencePart腾出空间

        // 将combined转换为字符串，并填充前导零以确保长度（但这里它已经是“足够”的长度了）
        // 注意：如果我们要得到一个真正的12位数字，我们需要对timePart进行不同的处理
        String idStr = String.format("%012d", combined).substring(combined < 1000 ? 10 : 8); // 这是一个错误的做法，仅用于说明

        // 实际上，上面的substring调用是错误的，因为我们不能从一个可能小于12位的数字中截取12位
        // 正确的做法是直接返回combined的字符串表示，但注意它可能不是12位
        return String.format("%08d%04d", timePart, sequencePart); // 更好的表示方式
    }

    public static void main(String[] args) {
        AAA a = new AAA(0);
        System.out.println(a.generateId());
    }
}
